﻿using System;

/*
 * 创建人：
 * 
 * 时间：
 * 
 * 说明：
 * 
 * 
 * 修改说明：
 * 
 * 
 */


namespace ConsoleTest.ChapterSeven
{
    [AttributeUsage(AttributeTargets.Method,AllowMultiple=false)]
    public class TestAttribute : System.Attribute
    {
        public TestAttribute()
        {
            System.Console.WriteLine("TestAttribute.ctor() Default ctor.");
        }

        public TestAttribute(int nTime)
        {
            System.Console.WriteLine("TestAttribute.ctor(int)");
            m_nTime = nTime;
        }
        private int m_nTime = 1;
        private bool m_Ignore = false;
        public bool Ignore
        {
            get { return m_Ignore; }
            set { m_Ignore = value; }
        }
        public int nTime
        {
            get { return m_nTime; }
            set { m_nTime = value; }
        }
    }

    public class TestAssembly
    {
        public static void Test()
        {
            System.Reflection.Assembly ass = System.Reflection.Assembly.GetExecutingAssembly();
            foreach (Type type in ass.GetTypes())
            {
                foreach (System.Reflection.MethodInfo method in type.GetMethods())
                {
                    object[] attributes = method.GetCustomAttributes(typeof(TestAttribute), false);
                    if (attributes.Length == 1)
                    {
                        TestAttribute testAttr = attributes[0] as TestAttribute;

                        if (!testAttr.Ignore)
                        {
                            object[] paras=new object[0];
                            object instance = System.Activator.CreateInstance(type);

                            for (int i = 0; i < testAttr.nTime; i++)
                            {
                                try
                                {
                                    method.Invoke(instance, paras);
                                }
                                catch (System.Reflection.TargetInvocationException ex)
                                {
                                    System.Console.WriteLine("The method {"+type.FullName+"."
                                        +method.Name+"} throw an exception of type"+ex.InnerException.GetType()+"during run #"+(i+1)+".");
                                }
                            }
                        }
                    }

                }
            }
        }
    }

    /// <summary>
    /// 用于自定义属性测试的类
    /// </summary>
    public class Foo
    {
        [Test()]
        public void Crash()
        {
            System.Console.WriteLine("Crash()");
            throw new System.ApplicationException();
        }

        int state = 0;

        [Test()]
        public void CrashTheSecondTime()
        {
            System.Console.WriteLine("CrashTheSecondTime()");
            state++;
            if (state == 2) throw new System.ApplicationException();
        }

        [Test()]
        public void DontCrash()
        {
            System.Console.WriteLine("DontCrash()");
        }

        [Test(Ignore=true)]
        public void CrashButIgnored()
        {
            System.Console.WriteLine("CrashButIgnored()");
            throw new System.ApplicationException();
        }
    }
}